package org.jflame.commons.convert;

import org.jflame.commons.util.CollectionHelper;
import org.jflame.commons.util.NumberHelper;
import org.jflame.commons.util.StringHelper;

import java.util.Set;

import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;

/**
 * string转为Number及子类.
 * 
 * @author charles.zhang
 * @param <T> T extends Number
 */
public class StringToNumberConverter<T extends Number> implements Converter<String,T>, ConvertibleType {

    private final Class<T> targetType;

    public StringToNumberConverter(Class<T> targetType) {
        this.targetType = targetType;
    }

    @Override
    public T convert(String source) {
        if (StringHelper.isEmpty(source)) {
            if (targetType.isPrimitive()) {
                throw new ConvertException("An empty string or null cannot be converted to a number");
            }
            return null;
        }
        return NumberHelper.parseNumber(source, this.targetType);
    }

    public Class<T> getTargetType() {
        return targetType;
    }

    @Override
    public Set<ImmutablePair<Class<?>,Class<?>>> getConvertibleTypes() {
        if (targetType.isPrimitive()) {
            return CollectionHelper.newSet(ImmutablePair.of(String.class, targetType),
                    ImmutablePair.of(String.class, ClassUtils.primitiveToWrapper(targetType)));
        } else if (ClassUtils.isPrimitiveWrapper(targetType)) {
            return CollectionHelper.newSet(ImmutablePair.of(String.class, targetType),
                    ImmutablePair.of(String.class, ClassUtils.wrapperToPrimitive(targetType)));
        } else {
            return CollectionHelper.newSet(ImmutablePair.of(String.class, targetType));
        }
    }
}
